Add D303 for Forerunner 301 track support. From David Scott. dave at recoildotorg
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Mon, 13 Jun 2005 19:56:20 +0000 (19:56 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Mon, 13 Jun 2005 19:56:20 +0000 (19:56 +0000)
gpsbabel/jeeps/gps.h
gpsbabel/jeeps/gpsapp.c
gpsbabel/jeeps/gpsapp.h
gpsbabel/jeeps/gpsprot.h
gpsbabel/jeeps/gpsserial.c

index 69dba75aacdf68d14c4e98fa756961f0e0c25bb2..b1de25c0e5edf9a0eaa55157be9d2466d7878bb6 100644 (file)
@@ -86,6 +86,7 @@ typedef struct GPS_STrack
     time_t   Time;             /* Unix time */
     float    alt;              /* Altitude */
     float    dpth;             /* Depth    */
+    int32    heartrate;                /* Heatrate as in Garmin 301 */
     int32    tnew;             /* New track? */
     int32    ishdr;            /* Track header? */
     int32    dspl;             /* Display on map? */
index 4648457532512a64b961fd35a5795784d52f991b..2c0faa2ce1b90582342ac9b0415c5645f4f4c3be 100644 (file)
@@ -512,10 +512,11 @@ static void GPS_A001(GPS_PPacket packet)
                            case 300: gps_trk_type = pD300; break;
                            case 301: gps_trk_type = pD301; break;
                            case 302: gps_trk_type = pD302; break;
+                           case 303: gps_trk_type = pD303; break;
                            case 310: gps_trk_hdr_type = pD310; break;
                            case 311: gps_trk_hdr_type = pD311; break;
                            case 312: gps_trk_hdr_type = pD312; break;
-                           default:  GPS_Protocol_Error(tag,data); break;
+                           default:  GPS_Protocol_Error(tag,data); break;
                    }
                    continue;
            }
@@ -3382,6 +3383,9 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk)
        case pD302:
            GPS_D302b_Get(&((*trk)[i]),rec->data);
            break;
+       case pD303:
+           GPS_D303b_Get(&((*trk)[i]),rec->data,rec->n);
+           break;
        default:
            GPS_Error("A301_GET: Unknown track protocol");
            return PROTOCOL_ERROR;
@@ -3791,6 +3795,84 @@ void GPS_D302b_Get(GPS_PTrack *trk, UC *data)
 }
 
 
+/* @func GPS_D303b_Get ******************************************************
+**
+** Get track data (A302 protocol) -- XXX used in Forerunner 301
+**
+** @param [w] trk [GPS_PTrack *] track
+** @param [r] data [UC *] packet data
+**
+** @return [void]
+************************************************************************/
+void GPS_D303b_Get(GPS_PTrack *trk, UC *data, UC length)
+{
+    UC *p;
+    uint32 t;
+    uint32 raw_lat, raw_lon;
+    int lat_undefined, lon_undefined;
+    int i;
+    
+    GPS_Diag("GPS_D303b_Get (length=%02d) ", length);
+    for (i = 0; i < length; i++) GPS_Diag("%02x ", data[i]);
+    GPS_Diag("\n");
+    
+    p=data;
+    
+    /* Latitude and longitude are sometimes invalid (0x7fffffff or 
+     * maybe 0xffffffff?) I guess this makes sense if the device is 
+     * reporting heart rate and time anyway.  I presume that latitude 
+     * and longitude are defined or left undefined together? 
+     */
+    raw_lat = GPS_Util_Get_Int(p);
+    lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff;
+    if (lat_undefined)
+       (*trk)->lat=0;
+    else
+       (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat);
+    p+=sizeof(int32);
+
+    raw_lon = GPS_Util_Get_Int(p);
+    lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff;
+    if (lon_undefined)
+       (*trk)->lon=0;
+    else
+       (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon);
+    p+=sizeof(int32);
+
+    if (lat_undefined != lon_undefined) 
+       GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated");
+
+    t = GPS_Util_Get_Uint(p);
+    if(!t || t==0x7fffffff || t==0xffffffff)
+       (*trk)->Time=0;
+    else
+       (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t);
+    p+=sizeof(uint32);
+
+    /* When latitude and longitude are undefined, this field seems to be 
+     * a constant on my receiver (51 59 04 69) */
+    (*trk)->alt = GPS_Util_Get_Float(p);
+    if (lat_undefined || lon_undefined) (*trk)->alt = 0.0f;
+    p+=sizeof(float);
+
+    /* Heartrate is reported as 0 if there is no signal from 
+     * a heartrate monitor.  A uint32 is a bit overkill, even 
+     * for me in my state of fitness. Perhaps this is actually 
+     * a char or uint16, leaving room for a trk_seg bool at the end? 
+     */
+    (*trk)->heartrate = GPS_Util_Get_Uint(p);
+    p+=sizeof(uint32);
+       
+    /* There doesn't seem to be a trk_seg bool, or at least I've not 
+     * observed it yet.  One possibility is to start a new segment 
+     * each time latitude and longitude are undefined? (Ie data from 
+     * the heartrate monitor but none from the GPS. */
+    (*trk)->tnew = 0;  
+
+    return;
+}
+
+
 /* @func GPS_D310_Get ******************************************************
 **
 ** Get track header data (A301 protocol)
index 4a36fdf4febb6f4c023d22d8b0646f4790b7f35c..eb13a6ab5cf3b94994c6fd7df638183a1b2f4ad6 100644 (file)
@@ -28,6 +28,7 @@ int32  GPS_D300_Get(GPS_PTrack *trk, int32 entries, int32 fd);
 void   GPS_D300b_Get(GPS_PTrack *trk, UC *data);
 void   GPS_D301b_Get(GPS_PTrack *trk, UC *data);
 void   GPS_D302b_Get(GPS_PTrack *trk, UC *data);
+void   GPS_D303b_Get(GPS_PTrack *trk, UC *data, UC length);
 void   GPS_D310_Get(GPS_PTrack *trk, UC *s);
 void   GPS_D311_Get(GPS_PTrack *trk, UC *s);
 void   GPS_D300_Send(UC *data, GPS_PTrack trk);
index 6a9e75bc10a26e1f8b94a677954158a792576b7b..1d0eb6a426c4e73bd9a489c9019e4e257751cea0 100644 (file)
@@ -174,6 +174,7 @@ int32 gps_rte_link_type;
 #define pD300 300
 #define pD301 301
 #define pD302 302
+#define pD303 303
 int32 gps_trk_type;
 
 
index 4883b93a36a16c0b90f405a80e13c9f8fdd43806..d1ced34408f121baa317a4f54142c7ab24332dd7 100644 (file)
@@ -39,7 +39,7 @@ char *rxdata[] = {
        "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03",
 
        /* Guessing from here down */
-       /* "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */
+       "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */
        "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */
        "10 06 02 0a 00 ee 10 03", /* Ack */
        "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */